package task

import (
	"encoding/json"
	"log"
	"math"
	"server/global"
	"server/internal/model"
	"server/internal/pkg/XiaoeApiSDK"
	"server/internal/pkg/wxpay"
	"server/utils/SnowFlake"
	"sort"
	"strconv"
	"sync"
	"time"
)

type Rule struct {
	Expend float64 `json:"expend"`
	Amount float64 `json:"amount"`
}

type Rule2 struct {
	Expend int     `json:"expend"`
	Amount float64 `json:"amount"`
}

var SyncResultsStatus = false

// SyncResults 同步需要发放的用户记录
func SyncResults(roomId string) {
	SyncResultsStatus = true
	defer func() {
		SyncResultsStatus = false
	}()

	log.Println("同步需要发放的用户记录>>开始")
	var room []model.Room
	Db := global.GL_DB
	now := time.Now() // 获取当前时间
	// 计算前一天的时间（减去24小时）
	oneDayAgo := now.Add(-24 * time.Hour).Format("2006-01-02")

	if roomId == "" {
		Db.Where("status = ? and grant_status = ?", 1, 0).Find(&room)
	} else {
		Db.Where("room_id = ?", roomId).Find(&room)
	}

	if len(room) > 0 {
		var ids []int
		for _, v := range room {
			ids = append(ids, v.ID)
		}
		Db.Model(&model.Room{}).Where("id in (?)", ids).Update("grant_status", 1)
	}

	for _, v := range room {

		num := 0
		var rule []Rule
		json.Unmarshal([]byte(v.Rule), &rule)
		//rule Expend为做小的
		sort.Slice(rule, func(i, j int) bool {
			return rule[i].Expend < rule[j].Expend
		})

		param := make(map[string]any)
		param["resource_id"] = v.RoomId                //直播id
		param["his_learn_time_min"] = v.WatchTime * 60 //最近进入时间（开始）
		param["page_size"] = 50                        //返回条数
		page := 1
		for true {
			param["page"] = page
			userList, err := XiaoeApiSDK.GetRoomUserList(param)
			if page == 1 {
				log.Println("房间:", v.RoomId, "同步开始，共计：", userList.Data.Total)
			}

			if userList.Code != 0 {
				log.Println("房间:", v.RoomId, "获取用户列表失败：", userList.Msg)
			}

			if err != nil {
				log.Println("房间:", v.RoomId, "获取用户列表失败:", err)
				break
			}

			if len(userList.Data.List) == 0 {
				log.Println("房间:", v.RoomId, "用户列表为0")
				break
			}

			var userIds []string
			for _, vv := range userList.Data.List {
				userIds = append(userIds, vv.UserId)
			}

			userInfoList, err := XiaoeApiSDK.GetUserOpenid(userIds)
			if err != nil {
				log.Println("批量获取openid失败", "err：", err)
				continue
			}

			for _, vv := range userList.Data.List {
				//获取用户观看时长
				record := vv.HisLearningTime / 60

				//record, err := XiaoeApiSDK.GetUserDailyLearningRecord(vv.UserId, v.RoomId, oneDayAgo)
				//if err != nil {
				//	log.Println("用户观看时长获取失败，用户:", vv.WxNickname, "用户ID:", vv.UserId, "err：", err)
				//	continue
				//}

				//未满足时间不统计
				if record < v.WatchTime {
					log.Println("为满足观看条件，用户:", vv.WxNickname, "用户ID:", vv.UserId, "，观看时长:", record)
					continue
				}

				Db = global.GL_DB
				var n int64
				Db.Model(&model.UserBill{}).Where("room_id=? and user_id = ?", v.RoomId, vv.UserId).Count(&n)
				if n > 0 {
					log.Println("领取记录已存在，用户:", vv.WxNickname, "用户ID:", vv.UserId, "，观看时长:", record)
					continue
				}

				//验证用户消费金额
				amount := 0.00
				payAmount := float64(vv.PayAmount)
				payAmount = payAmount / 100
				if len(rule) == 1 && rule[0].Expend == 0.00 {
					amount = rule[0].Amount
				} else {
					for _, val := range rule {
						if val.Expend <= payAmount {
							amount = val.Amount
						}
					}

				}

				if amount > 0 {
					//获取用户openid
					openid := ""
					for _, info := range userInfoList.Data.List {
						if info.UserId == vv.UserId {
							openid = info.WxOpenId
						}
					}

					//log.Println("用户:", vv.WxNickname, "，Openid:", openid, "用户ID:", vv.UserId,
					//	"，观看时长:", record, "，消费金额:", payAmount)

					bill := model.UserBill{}
					bill.RoomID = v.RoomId
					bill.UserID = vv.UserId
					bill.Nickname = vv.WxNickname
					bill.Avatar = vv.WxAvatar
					bill.Openid = openid
					bill.TotalViewingTime = record
					bill.PayAmount = payAmount //消费金额
					bill.Amount = amount
					bill.Status = 0
					bill.OrderNo = "XYX" + strconv.FormatInt(SnowFlake.GetId(), 10)
					bill.Date = oneDayAgo
					Db.Create(&bill)
					num++

				}

			}

			page++

		}

		Db.Model(&v).Updates(&map[string]any{"grant_status": 2, "date": oneDayAgo})
		log.Println("房间:", v.RoomId, "总计人数:", num)

	}
	log.Println("同步需要发放的用户记录<<结束")

}

func SyncResultsSS() {
	if SyncResultsStatus {
		log.Println("同步需要发放的用户记录 正在执行中，无法重复执行")
		return
	}

	SyncResults("")
}

var AwardBonusStatus = false

// AwardBonus 发红包
func AwardBonus(roomId string) {
	return
	AwardBonusStatus = true
	defer func() {
		AwardBonusStatus = false
	}()

	log.Println("发红包>>开始")
	var room []model.Room
	Db := global.GL_DB

	if roomId == "" {
		Db.Where("grant_status = ?", 2).Find(&room)

	} else {
		Db.Where("room_id = ?", roomId).Find(&room)
	}

	for _, v := range room {
		page := 1
		pageTotal := 20
		for true {
			var bill []model.UserBill
			if roomId == "" {
				Db.Where("room_id = ?", v.RoomId).Where("status = ?", 0).Limit(pageTotal).Offset((page - 1) * pageTotal).Find(&bill)
			} else {
				Db.Where("room_id = ?", v.RoomId).Where("status in ?", []int{0, 2}).Limit(pageTotal).Offset((page - 1) * pageTotal).Find(&bill)

			}

			page++
			if len(bill) == 0 {
				break
			}

			var wg sync.WaitGroup
			for _, vv := range bill {
				wg.Add(1)
				go func() {
					defer wg.Done()

					if vv.Openid == "" {
						// 更新状态
						Db.Model(&vv).Updates(&model.UserBill{
							Status: 2,
							Error:  "openid为空",
						})
					} else {
						// 发红包
						transferbatch, err := wxpay.Transferbatch(int64(math.Floor((vv.Amount)*100.00)), vv.Openid, vv.OrderNo)
						if err != nil {
							Db.Model(&vv).Updates(&model.UserBill{
								Status: 2,
								Error:  err.Error(),
							})
							log.Println("transferbatch-err:", err)
						} else {
							// 将结构体转换为JSON字节数组
							jsonData, _ := json.Marshal(transferbatch)
							// 更新状态
							Db.Model(&vv).Updates(&model.UserBill{
								Status: 1,
								Error:  string(jsonData),
							})
						}
					}

				}()
			}
			// 等待所有goroutine完成
			wg.Wait()
		}

		//统计发放总金额
		var totalAmount float64
		Db.Model(&model.UserBill{}).Where("room_id = ? and status=?", v.RoomId, 1).
			Select("sum(amount)").Scan(&totalAmount)

		//成功总条数
		var total int64
		Db.Model(&model.UserBill{}).Where("room_id = ? and status=?", v.RoomId, 1).Count(&total)

		// 发放完成
		Db.Model(&v).Update("grant_status", 3)
		Db.Model(&v).Update("grant_total", total)
		Db.Model(&v).Update("grant_amount", totalAmount)
	}

	log.Println("发红包<<结束")

}

func AwardBonusSS() {
	if AwardBonusStatus {
		log.Println("发红包 正在执行中，无法重复执行")
		return
	}

	AwardBonus("")
}

// ClearData 清理之前的记录 只保留本月的
func ClearData() {
	Db := global.GL_DB
	// 获取当前月份的第一天
	now := time.Now()
	firstDay := time.Date(now.Year(), now.Month()-1, 1, 0, 0, 0, 0, now.Location())
	log.Println(firstDay.String())
	// 删除不在当前月份的记录
	Db.Where("create_time < ?", firstDay.Unix()).Delete(&model.UserBill{})

}

// Ceshi 测试
func Ceshi() {
	XiaoeApiSDK.GetUserOpenid([]string{"u_684d57e3e929b_2pMvNV9VGY"})
}
